home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 4.iso / src / exampleCode / audio / midi / getmidi.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-08-02  |  7.9 KB  |  347 lines

  1. /*
  2.  * Copyright (C) 1994, Silicon Graphics, Inc.
  3.  * All Rights Reserved.
  4.  *
  5.  * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
  6.  * the contents of this file may not be disclosed to third parties, copied or
  7.  * duplicated in any form, in whole or in part, without the prior written
  8.  * permission of Silicon Graphics, Inc.
  9.  *
  10.  * RESTRICTED RIGHTS LEGEND:
  11.  * Use, duplication or disclosure by the Government is subject to restrictions
  12.  * as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
  13.  * and Computer Software clause at DFARS 252.227-7013, and/or in similar or
  14.  * successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
  15.  * rights reserved under the Copyright Laws of the United States.
  16.  */
  17.  
  18. /* getmidi.c link with -lmidi -lm -lC */
  19. /* usage: getmidi: <-cchannel> */
  20.  
  21. #include <midi.h>
  22. #include <miditime.h>
  23. #include <midiio.h>
  24. #include <signal.h>    
  25. /* for signal handler */
  26.  
  27. #define ALLCHANNELS 0xffff
  28.  
  29. int caught_sigint =  0;    /* completion flag */ 
  30. MItime timeofday;        /* time of day of first event */
  31. long gmlisten = ALLCHANNELS;
  32.  
  33. void 
  34. catch_sigint()
  35. {
  36.    caught_sigint=1;
  37. }
  38.  
  39. void printconfig(MIconfig *miconfig)
  40. {
  41. MItime mitime;
  42.  
  43.     printf("MICstamp\n  Timestamping is ");
  44.     switch(MICstamp(miconfig))
  45.     {
  46.         case MINOSTAMP:
  47.         {
  48.             printf("MINOSTAMP:no timestamp\n");
  49.             break;
  50.         }
  51.         case MIDELTASTAMP:
  52.         {
  53.             printf("MIDELTASTAMP:timestamp since previous event\n");
  54.             break;
  55.         }
  56.         case MIRELSTAMP:
  57.         {
  58.             printf("MIRELSTAMP:timestamp since first event\n");
  59.             break;
  60.         }
  61.         default:
  62.         {
  63.             printf("unknown timestamping type\n");
  64.         }
  65.     }
  66.  
  67.     printf("MICblocking\n  Blocking is ");
  68.     switch(MICblocking(miconfig))
  69.     {
  70.         case MIBLOCKING:
  71.         {
  72.             printf("MIBLOCKING:wait until message received\n");
  73.             break;
  74.         }
  75.         case MINONBLOCKING:
  76.         {
  77.             printf("MINONBLOCKING:no waiting until message received\n");
  78.             printf("   MICtimeout - will wait for ");
  79. /*
  80.             mitime = MICtimeout(miconfig);
  81.             printf("%f seconds.\n",(float)MItimegettotalsecs(mitime)+((float)MItimegetmicros(mitime) / 1000000.0));
  82. */
  83.             break;
  84.         }
  85.         default:
  86.         {
  87.             printf("unknown blocking type\n");
  88.         }
  89.     }
  90.  
  91. /* Need another example of MIdevice, thisone's outdated 
  92.     printf("MICdevice\n  Device is %d.\n", MICdevice(miconfig));
  93. */
  94. }
  95.  
  96.  
  97. void printMImessage(MImessage mimsg) 
  98. /* Keep in mind this is done with what I could make out from the
  99. MIDI specification from the klunker Roland Juno-106 */
  100. {
  101.     printf("  device = %d, channel = %d, length = %d.\n",
  102.         MIdevice(mimsg), MIchannel(mimsg), MIlength(mimsg));
  103.     printf("  status = ");
  104.     switch(MIstatus(mimsg) & MIDI_StatusMask)
  105.     {
  106. /*        case MIDI_ChannelVoice:  <-- these are the same */
  107.         case MIDI_NoteOff:        /* 0x80 - 1000 0000 */ 
  108.         {
  109.             printf("Note %x Off - velocity %x\n",
  110.                 MIbyte1(mimsg), MIbyte2(mimsg));
  111.             break;
  112.         }
  113.         case MIDI_NoteOn:        /* 0x90 - 1001 0000 */
  114.         {
  115.             if(MIbyte2(mimsg) == 0)  /* this is equivalent */
  116.                          /* to a MIDI_NoteOff  */
  117.             {
  118.                 printf("Note %x Off - velocity 00\n",
  119.                     MIbyte1(mimsg));
  120.             }
  121.             else
  122.             {
  123.                                 printf("Note %x On - velocity %x\n",
  124.                                         MIbyte1(mimsg), MIbyte2(mimsg));
  125.                         }
  126.             break;
  127.         }
  128.         case MIDI_PolyKeyPressure:    /* 0xa0 - 1010 0000 */
  129.         {
  130.             printf("PolyKeyPressure - %x\n",MIbyte2(mimsg));
  131.             break;
  132.         }
  133. /*         case MIDI_ControlChange:  <-- these are the same */
  134.         case MIDI_ChannelModeSelect:    /* 0xb0 - 1011 0000 */
  135.         {
  136.             switch(MIbyte1(mimsg))
  137.             {
  138.                 case MC_DamperPedal: /* 0x40 - 0100 0000 */
  139.                 {
  140.                     printf("Damper Pedal at %x\n",
  141.                         MIbyte2(mimsg));
  142.                 }
  143.                 case MC_AllNotesOff: /* 0x7b - 0111 1011 */
  144.                 {
  145.                     printf("All Notes Off at %x\n",
  146.                         MIbyte2(mimsg));
  147.                 }
  148.                 case MC_OmniModeOff: /* 0x7c - 0111 1100 */
  149.                 {
  150.                     printf("Omni Mode Off. next byte:%x\n",
  151.                         MIbyte2(mimsg));
  152.                 }
  153.                 case MC_OmniModeOn:  /* 0x7d - 0111 1101 */
  154.                 {
  155.                     printf("Omni Mode On. next byte:%x\n",
  156.                         MIbyte2(mimsg));
  157.                 }
  158.                 case MC_MonoModeOn:  /* 0x7e - 0111 1110 */
  159.                 {
  160.                     printf("Mono Mode On. next byte:%x\n",
  161.                         MIbyte2(mimsg));
  162.                 }
  163.                 case MC_PolyModeOn:  /* 0x7f - 0111 1111 */
  164.                 {
  165.                     printf("Poly Mode On. next byte:%x\n",
  166.                         MIbyte2(mimsg));
  167.                 }
  168.                 case MC_ModulationWheel:/* 0x01 - 0000 0001 */
  169.                 {
  170.                     printf("Modulation Wheel at %x\n",
  171.                         MIbyte2(mimsg));
  172.                 }
  173.             }
  174.             break;
  175.         }
  176.         case MIDI_ProgramChange:    /* 0xc0 - 1100 0000 */
  177.         {
  178.             printf("Program Change to #%x.\n",
  179.                 MIbyte1(mimsg));
  180.             break;
  181.         }
  182.         case MIDI_ChannelPressure:    /* 0xd0 - 1101 0000 */
  183.         {
  184.             printf("Channel Pressue - %x.\n",MIbyte1(mimsg));
  185.             break;
  186.         }
  187.         case MIDI_PitchBendChange:    /* 0xe0 - 1110 0000 */
  188.         {
  189.             printf("Pitch Bender at %x.\n",
  190.                 128 * MIbyte2(mimsg) + MIbyte1(mimsg));
  191.             break;
  192.         }
  193.     }
  194. }
  195.  
  196.  
  197. void printevents(MIevent *mievent, MItype *mitype, int num_events)
  198. {
  199. /* 
  200. Remember: within the MIevent structure is the timestamp and the message
  201. buffer. within the message buffer lies the MImessage structure and the buffer for system exclusive dats. 
  202. */
  203.  
  204. MItime         mitime;
  205. MImessage     mimsg;
  206. unsigned char   *misysexbuf;
  207. int i,j;
  208. static long eventnum = 0;
  209.  
  210.     if(!eventnum)    /* first event get time of day */
  211.     {
  212.         timeofday = MItimecurrentsystemtime(&timeofday);
  213.         printf("  STARTING time %d:%d:%f.\n",
  214.             MItimegethours(&timeofday), 
  215.             MItimegetminutes(&timeofday),
  216.             (float)MItimegetsecs(&timeofday) + 
  217.               ((float)MItimegetmicros(&timeofday) / 1000000.0));
  218.         eventnum++;
  219.     }
  220.  
  221.     for (i=0; i < num_events; i++)
  222.     {
  223.         mievent[i].dt = MItimecurrentsystemtime(&mievent[i].dt);
  224.         mitime = MItimesubtract(&mievent[i].dt,&timeofday);
  225.         mimsg  = mievent[i].mm.msgbuf; 
  226.         mitype = &mievent[i].t;
  227.         misysexbuf  = mievent[i].mm.sysexbuf;
  228.             if( (*mitype != MIMESSAGE) || 
  229.             ( (*mitype == MIMESSAGE) && 
  230.             ( (gmlisten == ALLCHANNELS) ||
  231.                  ( (gmlisten!=ALLCHANNELS)&&(MIchannel(mimsg)==gmlisten)))))
  232.         {
  233.             printf("EVENT #%d - ",eventnum++);
  234.             switch(*mitype)
  235.             {
  236.             case MIMESSAGE:
  237.             {
  238.                 printf("MIMESSAGE\n");
  239.                 printMImessage(mimsg);
  240.                 break;
  241.             }
  242.             case MISYSEX:
  243.             {
  244.                 printf("MISYSEX\n");
  245.  
  246.                 printf("%d bytes: ",mievent[i].count);
  247.                 for(j=0; (j<mievent[i].count-1)&&(j<8); j++)
  248.                     printf("%x, ",misysexbuf[j]);
  249.                 printf("%x %s\n",misysexbuf[j],
  250.                     ( (mievent[i].count > 8) ? "..." : ""));
  251.                 break;
  252.             }
  253.             case MIREALTIME:
  254.             {
  255.                 printf("MIREALTIME\n");
  256.                 break;
  257.             }
  258.             case MISYSCOM:
  259.             {
  260.                 printf("MISYSCOM\n");
  261.                 break;
  262.             }
  263.             default:
  264.             {
  265.                 printf("unknown\n");
  266.                 break;
  267.             }
  268.  
  269.             }
  270.         
  271.             printf("  at time %lf\n", MItimedouble(&mitime)/1000000.0 );
  272.         }
  273.     }
  274. }
  275.  
  276.  
  277. main(int argc, char **argv)
  278. {
  279. MIconfig     *miconfig = MInewconfig();
  280.                 /* returned a null pointer */
  281. MItime         *mitime; 
  282. const MItime         *mitimeStart; 
  283. MIevent     mievent[16];
  284. MItype         mitype[16];
  285. MIport         *miPort = MInewport();
  286.                 /* returned a null pointer */
  287. long hrs,mins,secs;
  288. int num;
  289.  
  290. /* config stuff */
  291.     
  292.     if(argc>1)
  293.     {
  294.         if(strncmp(argv[1],"-c",2) == 0)
  295.         {
  296.             gmlisten = atoi(argv[1]+2);
  297.         }
  298.     }
  299.     if(gmlisten != ALLCHANNELS)
  300.         printf("listening to MIDI channel %d.\n",gmlisten);
  301.     else
  302.         printf("listening to all MIDI channels.\n");
  303.         
  304.  
  305.     printf("DEFAULT CONFIGURATION:\n");
  306.     printconfig(miconfig);        /* print out default configuiration */
  307.  
  308.     MICsetstamp(miconfig,MIRELSTAMP);     
  309.     MICsetblocking(miconfig,MINONBLOCKING);    
  310. /* necessary for this program */
  311.  
  312.     printf("NEW CONFIGURATION:\n");
  313.     printconfig(miconfig);            /* print out the new config */
  314.  
  315.         sigset(SIGINT, catch_sigint); 
  316.                         /* set signal handler  */
  317.                         /* to catch ctrl-c */
  318.  
  319.     if (MIopen(miPort,"r", miconfig) == -1)    /* open midi port */
  320.     {
  321.         printf("MIopen: Couldn't open midi port\n");
  322.         exit(1);
  323.     }
  324.     printf("MIopen succeded.\n");
  325.  
  326.     printf("MIgetfd: file descriptor is %x\n.", MIgetfd(miPort));
  327.  
  328.     while(!caught_sigint)
  329.     {
  330.         num = MIreceive(miPort,mievent,1);     
  331.                     /* block here for 16  midi events */
  332.         if(num == -1)
  333.         {
  334.             printf("Error in MIrecieve.\n");
  335.             exit(1);
  336.         }
  337.         
  338.         printevents(mievent,mitype,num);    /* show what we got */
  339.     }
  340.  
  341.     MIclose(miPort);     /* close midi port */
  342.  
  343.                 /* free memory */
  344.     free(miPort);        
  345.     free(miconfig);
  346. }
  347.